package com.example.framework;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.Select;

import com.example.tests.UserRegisterFormParameter;

public class AppUnderTest {
	
	public static final String MY_ACCOUNT = "my/account";
	public static final String ACCOUNT_REGISTER = "account/register";
	public static final String HTTP_DEMO_REDMINE_ORG = "http://demo.redmine.org/";
	 public WebDriver driver;
	 public String baseUrl;
	 public StringBuffer verificationErrors = new StringBuffer();
	 
	public static String newUserLogin;
	public static String newUserFirstName;
	public static String newUserLastName;
	public static String newUserEmail;
	
	static private AppUnderTest globalApp;
	private NavigationHelper navHelper;
	
	public static AppUnderTest getInstance(String httpDemoRedmineOrg, String browser) throws Exception {
		if (globalApp != null){
			return globalApp;
		}
		globalApp = new AppUnderTest();
		globalApp.driver = new FirefoxDriver();
		globalApp.driver.get(httpDemoRedmineOrg);
		globalApp.baseUrl = HTTP_DEMO_REDMINE_ORG;
		globalApp.driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
		globalApp.navHelper = new NavigationHelper(globalApp);
		return globalApp;
	}

	public NavigationHelper navigateTo(){
		return navHelper;
	}

	public void assertMyAccountData() {
		try {
			assertEquals(newUserFirstName, driver.findElement(By.id("user_firstname"))
					.getAttribute("value"));
		} catch (Error e) {
			verificationErrors.append(e.toString());
		}
		assertTrue(isElementPresent(By.id("user_lastname")));
		try {
			assertEquals(newUserLastName, driver.findElement(By.id("user_lastname"))
					.getAttribute("value"));
		} catch (Error e) {
			verificationErrors.append(e.toString());
		}
		assertTrue(isElementPresent(By.id("user_mail")));
		try {
			assertEquals(newUserEmail,
					driver.findElement(By.id("user_mail"))
							.getAttribute("value"));
		} catch (Error e) {
			verificationErrors.append(e.toString());
		}
		assertTrue(isElementPresent(By.id("user_language")));
		try {
			assertEquals(
					"English",
					driver.findElement(
							By.cssSelector("html body.controller-my div#wrapper div#wrapper2 div#wrapper3 div#main div#content form#my_account_form.edit_user div.splitcontentleft fieldset.box p select#user_language option[selected=selected]"))
							.getText());
		} catch (Error e) {
			verificationErrors.append(e.toString());
		}
	}

	public void assertMyAccountPageIsOpened() {
		try {
			assertEquals(
					newUserLogin,
					driver.findElement(
							By.xpath("/html/body/div/div/div/div/div[2]/a"))
							.getText());
		} catch (Error e) {
			verificationErrors.append(e.toString());
		}

		try {
			assertEquals("My account",
					driver.findElement(By.linkText("My account")).getText());
		} catch (Error e) {
			verificationErrors.append(e.toString());
		}
		try {
			assertEquals("Sign out", driver
					.findElement(By.linkText("Sign out")).getText());
		} catch (Error e) {
			verificationErrors.append(e.toString());
		}
		try {
			assertTrue(isElementPresent(By.cssSelector("h2")));
		} catch (Error e) {
			verificationErrors.append(e.toString());
		}
	}

	public void assertSignInPageIsOpened() {
		try {
			assertEquals("http://demo.redmine.org/login",
					driver.getCurrentUrl());
		} catch (Error e) {
			verificationErrors.append(e.toString());
		}

		assertEquals("Login:", driver.findElement(By.cssSelector("td > label"))
				.getText());
		assertTrue(isElementPresent(By
				.xpath("//div[@id='login-form']/form/table/tbody/tr[2]/td/label")));
		assertTrue(isElementPresent(By.name("login")));
	}

	public void assertHomePageIsOpened() {
		assertEquals("Redmine demo", driver.findElement(By.cssSelector("h1"))
				.getText());
		assertEquals("Home", driver.findElement(By.cssSelector("h2")).getText());
		assertTrue(isElementPresent(By.linkText("Register")));
		assertTrue(isElementPresent(By.linkText("Sign in")));
	}

	protected boolean isElementPresent(By by) {
		try {
			driver.findElement(by);
			return true;
		} catch (NoSuchElementException e) {
			return false;
		}
	}

	public void assertRegistrationSuccessfull() {
		assertEquals("My account", driver
				.findElement(By.linkText("My account")).getText());
		driver.findElement(By.linkText("My account")).click();
		assertEquals("Information", driver
				.findElement(By.cssSelector("legend")).getText());
		assertTrue(isElementPresent(By.id("user_firstname")));
		try {
			assertEquals(UserRegisterFormParameter.getUserFirstName(), driver
					.findElement(By.id("user_firstname")).getAttribute("value"));
		} catch (Error e) {
			verificationErrors.append(e.toString());
		}
		assertTrue(isElementPresent(By.id("user_lastname")));
		try {
			assertEquals(UserRegisterFormParameter.getUserLastName(), driver
					.findElement(By.id("user_lastname")).getAttribute("value"));
		} catch (Error e) {
			verificationErrors.append(e.toString());
		}
		assertTrue(isElementPresent(By.id("user_mail")));
		try {
			assertEquals(UserRegisterFormParameter.getUserEmail(), driver
					.findElement(By.id("user_mail")).getAttribute("value"));
		} catch (Error e) {
			verificationErrors.append(e.toString());
		}
		assertTrue(isElementPresent(By.id("user_language")));
		try {
			assertEquals(
					UserRegisterFormParameter.userLanguage,
					driver.findElement(
							By.cssSelector("html body.controller-my div#wrapper div#wrapper2 div#wrapper3 div#main div#content form#my_account_form.edit_user div.splitcontentleft fieldset.box p select#user_language option[selected=selected]"))
							.getText());
		} catch (Error e) {
			verificationErrors.append(e.toString());
		}
	}

	public void assertRegisterPageIsOpened() {
		try {
			assertEquals(HTTP_DEMO_REDMINE_ORG + ACCOUNT_REGISTER,
					driver.getCurrentUrl());
		} catch (Error e) {
			verificationErrors.append(e.toString());
		}
	}

	public void fillRegisterForm(UserRegisterFormParameter parameterObject) {
		driver.findElement(By.id("user_login")).clear();
		driver.findElement(By.id("user_login")).sendKeys(
				UserRegisterFormParameter.getUserLogin());
		driver.findElement(By.id("user_password")).clear();
		driver.findElement(By.id("user_password")).sendKeys(
				UserRegisterFormParameter.userPass);
		driver.findElement(By.id("user_password_confirmation")).clear();
		driver.findElement(By.id("user_password_confirmation")).sendKeys(
				UserRegisterFormParameter.userPass);

		driver.findElement(By.id("user_firstname")).clear();
		driver.findElement(By.id("user_firstname")).sendKeys(
				UserRegisterFormParameter.getUserFirstName());

		driver.findElement(By.id("user_lastname")).clear();
		driver.findElement(By.id("user_lastname")).sendKeys(
				UserRegisterFormParameter.getUserLastName());
		driver.findElement(By.id("user_mail")).clear();
		driver.findElement(By.id("user_mail")).sendKeys(
				UserRegisterFormParameter.getUserEmail());

		new Select(driver.findElement(By.id("user_language")))
				.selectByVisibleText(UserRegisterFormParameter.userLanguage);
	}
}
